package com.step.ems

import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.navigation.NavHostController
import androidx.navigation.NavType
import androidx.navigation.compose.NavHost
import androidx.navigation.compose.composable
import androidx.navigation.compose.rememberNavController
import androidx.navigation.navArgument
import com.step.ems.Destinations.ELEVATOR_DETAIL_ROUTE
import com.step.ems.Destinations.ELEVATOR_PAGE_ROUTE
import com.step.ems.Destinations.HOME_ROUTE
import com.step.ems.Destinations.ID
import com.step.ems.Destinations.IMAGE_PREVIEW_ROUTE
import com.step.ems.Destinations.LOGIN_ROUTE
import com.step.ems.Destinations.SETTING_ROUTE
import com.step.ems.Destinations.URGENT_DETAIL_ROUTE
import com.step.ems.Destinations.URGENT_PAGE_ROUTE
import com.step.ems.Destinations.URL
import com.step.ems.Destinations.WB_DETAIL_ROUTE
import com.step.ems.Destinations.WB_ITEM_ROUTE
import com.step.ems.Destinations.WB_PAGE_ROUTE
import com.step.ems.common.EventBus
import com.step.ems.common.LoginEvent
import com.step.ems.common.NavBackEvent
import com.step.ems.component.ImagePreviewScreen
import com.step.ems.pages.elevator.ElevatorDetailScreen
import com.step.ems.pages.elevator.ElevatorPageScreen
import com.step.ems.pages.home.HomePage
import com.step.ems.pages.login.LoginScreen
import com.step.ems.pages.setting.SettingScreen
import com.step.ems.pages.urgent.UrgentDetailScreen
import com.step.ems.pages.urgent.UrgentPageScreen
import com.step.ems.pages.wb.WbDetailScreen
import com.step.ems.pages.wb.WbItemScreen
import com.step.ems.pages.wb.WbPageScreen
import kotlinx.coroutines.flow.collectLatest
import kotlinx.coroutines.flow.filterIsInstance
import soup.compose.material.motion.animation.materialSharedAxisYIn
import soup.compose.material.motion.animation.materialSharedAxisYOut
import soup.compose.material.motion.animation.rememberSlideDistance
import soup.compose.material.motion.animation.translateYIn
import soup.compose.material.motion.animation.translateYOut

object Destinations {
    const val ID = "id"
    const val URL = "url"
    const val LOGIN_ROUTE = "login"
    const val HOME_ROUTE = "home"
    const val SETTING_ROUTE = "setting"
    const val ELEVATOR_PAGE_ROUTE = "elevatorPage"
    const val ELEVATOR_DETAIL_ROUTE = "elevatorDetail/{id}"
    const val URGENT_PAGE_ROUTE = "urgentPage"
    const val URGENT_DETAIL_ROUTE = "urgentDetail/{id}"
    const val WB_PAGE_ROUTE = "wbPage"
    const val WB_DETAIL_ROUTE = "wbDetail/{id}"
    const val WB_ITEM_ROUTE = "wbItem/{id}"
    const val IMAGE_PREVIEW_ROUTE = "imagePreview?url={url}"
}

@Composable
fun EmsNavHost(
    navController: NavHostController = rememberNavController(),
) {
    LaunchedEffect(Unit) {
        EventBus.events.filterIsInstance<NavBackEvent>().collectLatest {
            navController.popBackStack()
        }
    }
    LaunchedEffect(Unit) {
        EventBus.events.filterIsInstance<LoginEvent>().collectLatest {
            navController.navigate(LOGIN_ROUTE)
        }
    }

    val slideDistance = rememberSlideDistance()
    return NavHost(
        navController = navController,
        startDestination = HOME_ROUTE,
        enterTransition = { materialSharedAxisYIn(true, slideDistance) },
        exitTransition = { materialSharedAxisYOut(true, slideDistance) },
        popEnterTransition = { materialSharedAxisYIn(false, slideDistance) },
        popExitTransition = { materialSharedAxisYOut(false, slideDistance) },
    ) {
        composable(HOME_ROUTE) {
            HomePage(
                toElevator = { navController.navigate(ELEVATOR_PAGE_ROUTE) },
                toUrgent = { navController.navigate(URGENT_PAGE_ROUTE) },
                toWb = { navController.navigate(WB_PAGE_ROUTE) },
                toSettings = { navController.navigate(SETTING_ROUTE) }
            )
        }
        composable(
            route = LOGIN_ROUTE,
            enterTransition = { translateYIn { it } },
            exitTransition = { translateYOut { it } },
        ) {
            LoginScreen(
                toHome = {
                    navController.navigate(HOME_ROUTE) {
                        popUpTo(navController.graph.id) { inclusive = true }
                    }
                }
            )
        }
        composable(ELEVATOR_PAGE_ROUTE) {
            ElevatorPageScreen(onItemClick = {
                navController.navigate("elevatorDetail/${it.id}")
            })
        }
        composable(
            ELEVATOR_DETAIL_ROUTE,
            arguments = listOf(navArgument(ID) { type = NavType.IntType })
        ) {
            ElevatorDetailScreen()
        }
        composable(URGENT_PAGE_ROUTE) {
            UrgentPageScreen(onItemClick = {
                navController.navigate("urgentDetail/${it.id}")
            })
        }
        composable(
            URGENT_DETAIL_ROUTE,
            arguments = listOf(navArgument(ID) { type = NavType.IntType })
        ) {
            UrgentDetailScreen()
        }
        composable(WB_PAGE_ROUTE) {
            WbPageScreen(onItemClick = {
                navController.navigate("wbDetail/${it.id}")
            })
        }
        composable(
            WB_DETAIL_ROUTE,
            arguments = listOf(navArgument(ID) { type = NavType.IntType })
        ) {
            WbDetailScreen(
                gotoItem = {
                    navController.navigate("wbItem/${it}")
                },
                onPhotoClick = {
                    navController.navigate("imagePreview?url=${it}")
                })
        }
        composable(
            WB_ITEM_ROUTE,
            arguments = listOf(navArgument(ID) { type = NavType.IntType })
        ) {
            WbItemScreen()
        }
        composable(
            IMAGE_PREVIEW_ROUTE,
            arguments = listOf(navArgument(URL) { type = NavType.StringType })
        ) { backStackEntry ->
            val url = backStackEntry.arguments?.getString(URL)
            ImagePreviewScreen(url)
        }
        composable(SETTING_ROUTE) {
            SettingScreen {
                navController.navigate(LOGIN_ROUTE) {
                    if (it) {
                        popUpTo(navController.graph.id) { inclusive = true }
                    }
                }
            }
        }
    }
}